void main() {
  print('== Dart 空安全示例 ==');

  // 1. 可空类型和非空类型
  nullableAndNonNullableTypes();

  // 2. 非空断言操作符 (!)
  nonNullAssertion();

  // 3. 空值合并运算符 (??)
  nullCoalescingOperator();

  // 4. 空值合并赋值 (??=)
  nullAwareAssignment();

  // 5. late 变量
  lateVariables();

  // 6. 可空类型的方法和属性访问 (?.)
  nullableMethodAndPropertyAccess();
}

// 1. 可空类型和非空类型
void nullableAndNonNullableTypes() {
  print('\n== 可空类型和非空类型 ==');

  // 非空类型，必须初始化
  String nonNullableString = '非空字符串';
  // nonNullableString = null; // 错误：不能将 null 赋给非空类型

  // 可空类型，使用 ? 标记
  String? nullableString; // 可以不初始化
  nullableString = null; // 可以赋值为 null
  nullableString = '可空字符串';

  print('nonNullableString: $nonNullableString');
  print('nullableString: $nullableString');
}

// 2. 非空断言操作符 (!)
void nonNullAssertion() {
  print('\n== 非空断言操作符 (!) ==');

  String? nullableString = '非空值';

  // 使用 ! 断言该变量非空
  String nonNullableString = nullableString!;
  print('nonNullableString: $nonNullableString');

  // 如果断言失败（变量为 null），会抛出异常
  nullableString = null;
  // String errorString = nullableString!; // 运行时错误：Null check operator used on a null value
}

// 3. 空值合并运算符 (??)
void nullCoalescingOperator() {
  print('\n== 空值合并运算符 (??) ==');

  String? nullableString1 = null;
  String? nullableString2 = '有值的字符串';

  // 如果左边为 null，则使用右边的值
  String result1 = nullableString1 ?? '默认值';
  String result2 = nullableString2 ?? '默认值';

  print('result1: $result1'); // 输出: 默认值
  print('result2: $result2'); // 输出: 有值的字符串
}

// 4. 空值合并赋值 (??=)
void nullAwareAssignment() {
  print('\n== 空值合并赋值 (??=) ==');

  String? nullableString;

  // 如果变量为 null，则赋值
  nullableString ??= '初始值';
  print('nullableString: $nullableString'); // 输出: 初始值

  // 如果变量已有值，则不赋值
  nullableString ??= '新值';
  print('nullableString: $nullableString'); // 输出: 初始值
}

// 5. late 变量
void lateVariables() {
  print('\n== late 变量 ==');

  // late 修饰的非空变量，可以稍后初始化
  late String lateString;

  // 在使用前必须初始化
  lateString = '延迟初始化的值';
  print('lateString: $lateString');

  // late 也可以用于延迟初始化的 final 变量
  late final String lateFinalString;
  lateFinalString = '延迟初始化的 final 值';
  print('lateFinalString: $lateFinalString');

  // 如果在初始化前使用，会抛出异常
  // late String uninitializedLateString;
  // print(uninitializedLateString); // 运行时错误：LateInitializationError
}

// 6. 可空类型的方法和属性访问 (?.)
void nullableMethodAndPropertyAccess() {
  print('\n== 可空类型的方法和属性访问 (?.) ==');

  String? nullableString = 'Hello';

  // 如果 nullableString 为 null，不会调用 length 属性，直接返回 null
  int? length = nullableString?.length;
  print('length: $length'); // 输出: 5

  nullableString = null;
  length = nullableString?.length;
  print('length: $length'); // 输出: null
}    